还没有笔记
选中页面文字后点击「高亮」按钮添加
COMS W3157
Borowski 博士
```
$ ls -l
total 36 <- total number of blocks used
drwxrwxr-x 2 user user 4096 Jan 28 23:36 Desktop
drwxr-xr-x 2 user user 4096 Jan 23 14:47 Documents
...
drwxrwxr-x
```
第一个字符是文件类型,d -> 目录,l -> 链接,c -> 字符设备,b -> 块设备,- -> 常规文件。第一个 rwx 表示用户具有读、写和执行权限。第二个 rwx 表示组具有读、写和执行权限。第三组是 r-x,其他用户没有写权限。
```
$ ls -l
total 36
drwxrwxr-x 2 user user 4096 Jan 28 23:36 Desktop
drwxr-xr-x 2 user user 4096 Jan 23 14:47 Documents
...
```
硬链接计数是红色的。
拥有该文件的用户是蓝色的。
组是绿色的。
文件大小(以字节为单位)是紫色的。
最后修改日期是棕褐色的。
文件的名称是黑色的。

可以很容易地将权限设置视为一系列位(计算机就是这样考虑它们的)。工作原理如下:
rwxrwxrwx = 111111111
rw-rw-rw- = 110110110
rwx------ = 111000000
| rwx=111,二进制 =7 | -wx=011,二进制 =3 |
| :--- | :--- |
| rw-=110,二进制 =6 | -w-=010,二进制 =2 |
| r-x=101,二进制 =5 | --x=001,二进制 =1 |
| r--=100,二进制 =4 | ---=000,二进制 =0 |
语法:chmod [options] [mode] file...
| 参考 | 类别 | 描述 |
| :--- | :--- | :--- |
| u | 所有者 | 文件的所有者 |
| g | 组 | 属于该文件的组的用户 |
| o | 其他 | 既不是文件的所有者也不是该文件的组的成员的用户 |
| a | 所有 | 以上三者,等同于 ugo |
| 运算符 | 描述 |
| :--- | :--- |
| + | 将指定的模式添加到指定的类别 |
| - | 从指定的类别中删除指定的模式 |
| = | 指定的模式将成为指定类别的精确模式 |
假设我们从以下开始:
-rwxr-xr-x user user header.sh
$ chmod g+w header.sh
-rwxrwxr-x user user header.sh
$ chmod o-x header.sh
-rwxrwxr-- user user header.sh
$ chmod 744 header.sh
-rwxr--r-- user user header.sh

```
```
lrwxrwxrwx 1 user user 11 Jan 23 14:49 shared -> /mnt/shared
注意文件类型是 'l'。
符号链接就像快捷方式:target -> source
要显示隐藏文件,请在 ls 命令中使用 -a 标志。
| $ ls -a | | |
| :--- | :--- | :--- |
| . | .gnupg | shared |
| .. | .junk | .sudo_as_admin_successful |
| .bash_history | junk | Templates |
| .bash_logout | .lesshst | .vboxclient-clipboard.pid |
| .bashrc | .local | .vboxclient-display.pid |
| .cache | Music | .vboxclient-draganddrop.pid |
| .config | Pictures | .vboxclient-seamless.pid |
| Desktop | .profile | Videos |
| Documents | Public | .Xauthority |
| Downloads | .recyclebin | .xsession-errors |
每个 bash 脚本的第一行必须是 #!/bin/bash 以调用 shell。这将在我们的 Linux 环境中工作。
您也可以使用:
为了可移植性:不同的 *nix 系统将 bash 放在不同的位置,使用 /usr/bin/env 是一种运行 $PATH 中找到的第一个 bash 的变通方法。
#! 称为 "shebang"。
这行必须出现在任何注释之前。
```
size_flag=0
```
```
####################################################################################################
####################################################################################################
```
要设置变量,请写
要读取变量的值,请在其前面加上 $。
echo "Count is $count."
读取 $ # 会告诉您提供给脚本的命令行参数的数量。
假设您执行:./runme.sh A B C
$# 将等于 3。
```
$ declare -a array
$ array[0]="hi"
$ array[1]="bye"
$ echo ${array[0]}
hi
$ echo ${array[1]}
bye
$ echo ${array[@]}
hi bye
$ echo ${array[*]}
hi bye
$ echo ${#array[@]}
2
$ echo ${#array[*]}
2
```
```
cat << ENDOFTEXT
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
ENDOFTEXT
```
作为多行字符串字面量非常有用,它保留了文本中的换行符和其他空白字符(包括缩进)。
```
loat << ENDOFTEXT
Lorem ipsum dolor sit amet, consectetur
adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna
aliqua.
ENDOFTEXT
) > loremipsum.txt
```
从脚本内部创建文本文件。
```
$ basename /home/user/shared/sandbox/waterjugpuzzle.cpp
waterjugpuzzle.cpp
```
在脚本中:
```
file="/home/user/shared/sandbox/waterjugpuzzle.cpp"
echo $(basename "$file")
... or ...
varname=$(basename "$file")
```
在 () 中调用命令会使用子 shell。要读取在子 shell中执行的程序的输出,请在 () 前面加上 $。
```
if [ ! -d "$dirname" ]; then # if directory doesn't exist
fi
if [ ! -f "$filename" ]; then # if file doesn't exist
fi
if [ $var -eq 1 ]; then # if variable's value equals 1
fi
```
另请参阅整数比较:-ne、-lt、-gt、-le、-ge
字符串比较:==、!=
```
a=5
b=6
total=$(( a + b ))
echo $total
index=0
(( ++index )) # or
(( index++ )) # or
index=$(( index+1 )) # or
(( index=index+1 )) # or
(( index+=1 ))
echo $index
index is now 5
```
我们可以通过将变量声明为 readonly 来使其成为 "常量"。在初始赋值之后,该变量不可更改。这对于在脚本的整个生命周期中其值应保持固定的全局变量非常有用。
```
$ readonly a=3
$ a=4
-bash: a: readonly variable
```
可以将变量从可写更改为 readonly。
```
$ b=3
$ readonly b=4
```
要在 bash 中定义函数,请编写函数名、开括号和闭括号,以及开花括号和闭花括号。
```
myfunction() {
echo "Hello, world!"
}
```
参数是位置的,从 $1 开始。如果您希望变量具有语义意义,请在函数内部重新分配它们。
```
myfunction() {
local name=$1
echo "Hello, $name!"
}
```
在函数中,局部变量仅在该函数块内有意义。这是首选方法,这样您就不会无意中覆盖同名全局变量的值。
要调用函数,请使用任何参数调用函数名,每个参数之间用空格分隔。请务必用引号引起来包含空格的字符串,以免它们被分成多个参数。
myfunction "Dr. B"
您可以将参数传递给脚本。
./myscript This is cool.
它们是位置的。在脚本内部,
```
$0: ./myscript
$1: This
$2 is
$3 cool.
```
然而,有时我们可能需要解析标志,后跟位置参数,例如
./parseargs.sh -s a.txt b.txt getopts 内置于 bash 中,是一种方便的方法,用于解析所有标志(即那些带有短划线后跟字母的选项),同时还以位置方式处理所有剩余参数。
size_flag=0
while getopts ":s" option; do

假设我们编写了一个名为 tail.sh 的脚本,仅打印文件 a.txt、b.txt 和 c.txt 的最后 -n 行。
假设我们再次抑制内部错误消息,为 getopts 编写 optstring。
假设我们编写了一个名为 tail.sh 的脚本,仅打印文件 a.txt、b.txt 和 c.txt 的最后 -n 行。
假设我们再次抑制内部错误消息,为 getopts 编写 opstring。
答案::n:
我们还需要在 n 后面加上一个冒号,因为我们需要在命令行上 -n 之后立即检索用户提供的行数。
假设我们的 tail 脚本按如下方式调用
./tail.sh -n 5 a.txt b.txt c.txt
我们将得到以下命令行参数数组。
| 1 | 1 | 2 | 3 | 4 | 5 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| ./tail.sh | -n | 5 | a.txt | b.txt | c.txt |
OPTIND 是命令行上下一个参数的索引,在所有标志都用 getopts 解析后,所以 OPTIND 将是 3。
# 显示从 $1` 开始的**(位置)参数**的数量。在这种情况下,打印 `$ # 显示 5。
| 0 | 1 | 2 | 3 | 4 | 5 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| shift | -n | 5 | a.txt | b.txt | c.txt |
| 0 | 1 | 2 | 3 | 4 | 5 |
| ./tail.sh | a.txt | b.txt | c.txt | (空白) | (空白) |
您可以方便地遍历位置参数,如下所示:
```
for f in "$@"; do
echo "$f"
```
done
$@ 扩展为位置参数,从 1 开始。当在双引号内进行扩展时,每个参数扩展为单独的字符串。
shellcheck <您的脚本名称>,例如
shellcheck tail.sh